"""
xiongmao-parse-mp3项目日志配置文件
功能特性：
- 按天分割：每天午夜创建新日志文件
- 按大小分割：文件超过200MB时创建新的文件
- 自动清理：保留30天的历史日志
- 多模块支持：支持不同模块的独立日志
"""

import os
import logging
import time
from logging.handlers import TimedRotatingFileHandler


class SizeAndTimeRotatingFileHandler(TimedRotatingFileHandler):
    """
    自定义日志处理器：既按时间分割又按大小分割
    - 按天分割：每天午夜创建新文件
    - 按大小分割：当文件超过指定大小时创建带自增ID的新文件
    """
    
    def __init__(self, filename, when='midnight', interval=1, backupCount=0, 
                 encoding=None, delay=False, utc=False, atTime=None, 
                 maxBytes=200*1024*1024, maxFiles=10):  # 默认200MB
        super().__init__(filename, when, interval, backupCount, encoding, delay, utc, atTime)
        self.maxBytes = maxBytes
        self.maxFiles = maxFiles
        self.current_file_index = 0
        self.base_filename = filename
        
    def shouldRollover(self, record):
        """
        检查是否需要轮转日志文件
        1. 首先检查时间轮转（按天）
        2. 然后检查大小轮转（按大小）
        """
        # 先检查时间轮转
        time_rollover = super().shouldRollover(record)
        if time_rollover:
            # 时间轮转时重置文件索引
            self.current_file_index = 0
            return True
            
        # 检查文件大小轮转
        if self.stream is None:
            self.stream = self._open()
        if self.maxBytes > 0:
            self.stream.seek(0, 2)  # 移动到文件末尾
            if self.stream.tell() >= self.maxBytes:
                return True
        return False
        
    def doRollover(self):
        """
        执行日志文件轮转
        """
        if self.stream:
            self.stream.close()
            self.stream = None
            
        # 检查是否是大小轮转（而非时间轮转）
        is_size_rollover = hasattr(self, '_size_rollover') and self._size_rollover
        
        if is_size_rollover:
            # 大小轮转：创建带自增ID的文件名
            self.current_file_index += 1
            
            # 获取当前日期后缀
            now = int(time.time())
            time_tuple = time.localtime(now)
            today_suffix = time.strftime(self.suffix, time_tuple)
            
            # 构建新的文件名
            dir_name = os.path.dirname(self.base_filename)
            base_name = os.path.basename(self.base_filename)
            name_part, ext_part = os.path.splitext(base_name)
            
            # 创建带日期和序号的文件名
            new_filename = f"{name_part}-{today_suffix}-{self.current_file_index:03d}{ext_part}"
            self.baseFilename = os.path.join(dir_name, new_filename)
            
            # 记录轮转信息
            logging.getLogger().info(f"📏 日志文件达到200MB限制，创建新文件: {new_filename}")
            self._size_rollover = False
        else:
            # 时间轮转：使用原有逻辑，但需要处理文件名
            if self.current_file_index > 0:
                # 如果之前有大小轮转，需要将baseFilename重置为基础文件名
                self.baseFilename = self.base_filename
                self.current_file_index = 0
            super().doRollover()
            logging.getLogger().info(f"🕒 新的一天开始，创建新日志文件")
            
        # 打开新的日志文件
        if not self.delay:
            self.stream = self._open()
            
    def emit(self, record):
        """
        输出日志记录
        """
        try:
            if self.shouldRollover(record):
                # 标记这是大小轮转还是时间轮转
                if self.stream is not None:
                    self.stream.seek(0, 2)
                    self._size_rollover = self.stream.tell() >= self.maxBytes
                else:
                    self._size_rollover = False
                self.doRollover()
            super(TimedRotatingFileHandler, self).emit(record)
        except Exception:
            self.handleError(record)


def setup_logging(log_level=logging.INFO, log_dir=None):
    """
    配置xiongmao-parse-mp3项目的日志系统
    
    Args:
        log_level: 日志级别，默认INFO
        log_dir: 日志目录，默认为logs
    """
    # 确保日志目录存在 - 支持环境变量配置
    if log_dir is None:
        log_dir = os.getenv("LOG_DIR", "logs")  # 默认使用logs目录，可通过环境变量覆盖
    os.makedirs(log_dir, exist_ok=True)
    
    # 创建根日志记录器
    logger = logging.getLogger()
    logger.setLevel(log_level)
    
    # 清除现有的处理器
    logger.handlers.clear()
    
    # 日志格式
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    # 1. 主应用日志文件处理器
    app_file_handler = SizeAndTimeRotatingFileHandler(
        filename=os.path.join(log_dir, "xiongmao-parse-mp3.log"),
        when='midnight',
        interval=1,
        backupCount=30,  # 保留30天的日志文件
        encoding='utf-8',
        maxBytes=200*1024*1024,  # 200MB
        maxFiles=10  # 每天最多10个文件
    )
    app_file_handler.setLevel(log_level)
    app_file_handler.setFormatter(formatter)
    app_file_handler.suffix = "%Y-%m-%d"  # 日志文件后缀格式
    
    # 2. 控制台处理器 - 保持控制台输出
    console_handler = logging.StreamHandler()
    console_handler.setLevel(log_level)
    console_handler.setFormatter(formatter)
    
    # 添加处理器到根日志记录器
    logger.addHandler(app_file_handler)
    logger.addHandler(console_handler)
    
    # 记录日志系统初始化信息
    logging.info(f"🚀 xiongmao-parse-mp3日志系统已初始化")
    logging.info(f"📁 日志文件保存到: {log_dir}/xiongmao-parse-mp3.log")
    logging.info(f"🕒 按天分割：每天午夜自动创建新文件")
    logging.info(f"📏 按大小分割：单文件超过200MB时创建新文件")
    logging.info(f"📅 保留策略：保留30天历史记录")
    logging.info(f"🔄 文件命名：xiongmao-parse-mp3-2024-01-01.log, xiongmao-parse-mp3-2024-01-01-001.log 等")
    
    return logger


def setup_module_logging(module_name, log_level=logging.INFO, log_dir=None):
    """
    为特定模块设置独立的日志记录器
    
    Args:
        module_name: 模块名称（如：image_generation, qiniu_upload, webhook等）
        log_level: 日志级别，默认INFO
        log_dir: 日志目录，默认为logs
    """
    # 确保日志目录存在
    if log_dir is None:
        log_dir = os.getenv("LOG_DIR", "logs")
    os.makedirs(log_dir, exist_ok=True)
    
    # 创建模块专用日志记录器
    logger = logging.getLogger(module_name)
    logger.setLevel(log_level)
    
    # 如果已经有处理器，不重复添加
    if logger.handlers:
        return logger
    
    # 日志格式
    formatter = logging.Formatter(f'%(asctime)s - {module_name} - %(levelname)s - %(message)s')
    
    # 模块专用文件处理器
    module_file_handler = SizeAndTimeRotatingFileHandler(
        filename=os.path.join(log_dir, f"xiongmao-parse-mp3-{module_name}.log"),
        when='midnight',
        interval=1,
        backupCount=30,  # 保留30天的日志文件
        encoding='utf-8',
        maxBytes=200*1024*1024,  # 200MB
        maxFiles=10  # 每天最多10个文件
    )
    module_file_handler.setLevel(log_level)
    module_file_handler.setFormatter(formatter)
    module_file_handler.suffix = "%Y-%m-%d"
    
    # 添加处理器
    logger.addHandler(module_file_handler)
    
    # 防止向父级记录器传播（避免重复记录）
    logger.propagate = False
    
    logging.info(f"📝 模块日志记录器已创建: {module_name}")
    
    return logger


def get_logger(name=None):
    """
    获取日志记录器实例
    
    Args:
        name: 记录器名称，None表示根记录器
    
    Returns:
        logging.Logger: 日志记录器实例
    """
    return logging.getLogger(name)


# 项目日志记录器 - 统一使用主日志记录器
class ProjectLoggers:
    """项目日志记录器集合 - 统一记录到主日志文件"""
    
    @staticmethod
    def get_image_generation_logger():
        """获取图片生成模块日志记录器"""
        return get_logger("image_generation")
    
    @staticmethod
    def get_qiniu_logger():
        """获取七牛云上传模块日志记录器"""
        return get_logger("qiniu_upload")
    
    @staticmethod
    def get_webhook_logger():
        """获取Webhook回调模块日志记录器"""
        return get_logger("webhook")
    
    @staticmethod
    def get_database_logger():
        """获取数据库操作模块日志记录器"""
        return get_logger("database")
    
    @staticmethod
    def get_api_logger():
        """获取API路由模块日志记录器"""
        return get_logger("api_router")
    
    @staticmethod
    def get_pc_client_logger():
        """获取PC端客户端模块日志记录器"""
        return get_logger("pc_client")

    @staticmethod
    def get_main_logger():
        """获取主应用日志记录器"""
        return get_logger()
    
    @staticmethod
    def get_service_logger():
        """获取服务层日志记录器"""
        return get_logger("service")


# 初始化主日志系统
def init_logging():
    """初始化项目日志系统"""
    setup_logging()
    logging.info("🎯 xiongmao-parse-mp3项目日志系统完全加载")


# 如果直接运行此文件，则初始化日志系统
if __name__ == "__main__":
    init_logging()
    
    # 测试不同模块的日志记录器
    img_logger = ProjectLoggers.get_image_generation_logger()
    img_logger.info("测试图片生成模块日志")
    
    qiniu_logger = ProjectLoggers.get_qiniu_logger()
    qiniu_logger.info("测试七牛云上传模块日志")
    
    webhook_logger = ProjectLoggers.get_webhook_logger()
    webhook_logger.info("测试Webhook回调模块日志") 